<?php
/** require:
 *  __PHY_LIB
 */
require_once(__PHY_LIB . "/class/Query.class.php");

class Item extends Query {
/// definition and constructor ///
	var $mKeyField = null;
	var $mKeyAutoIncrement = true;
	var $mAllField = array();
	var $mAttrField = array();
	var $mAttrLable = array();

	function Item($dsn=null) {
		Query::Query($dsn);
	}

/// configure functions ///
	function cfgAllField($fields) {
		if (is_array($fields)){
			$this->mAllField = $fields;
		}
		else {
			$r = explode(",", trim($fields, " ,"));
			$this->mAllField = array_combine($r, $r);
		}
	}
	function cfgAttrField($fields) {
		if (is_array($fields)){
			$this->mAttrField = $fields;
		}
		else {
			$r = explode(",", trim($fields, " ,"));
			$this->mAttrField = array_combine($r, $r);
		}
	}
	function cfgAttrLable($lable) {
		if (is_array($lable)){
			$this->mAttrLable = $lable;
		}
		else {
			$r = explode(",", trim($lable, " ,"));
			$this->mAttrLable = array_combine($r, $r);
		}
	}

	function cfgKeyField($field, $auto=true) {
		$this->mKeyField = $field;
		$this->mKeyAutoIncrement = (bool)$auto;
	}

	function cfgField($fields) {
		if (is_array($fields)) {
			Query::cfgField($fields);
		}
		elseif ("*" == $fields) {
			Query::cfgField(array_keys($this->mAllField));
		}
		else {
			Query::cfgField($fields);
		}
	}

/// execute functions ///
	function load() {
		$this->loadOne();
	}

	function loadUnique($field, $value) {
		$this->cfgWhere($field . "='".addslashes($value)."'");
		$this->load();
		if ($this->mKeyField && 0 < ($id = $this->getID())) {
			$this->cfgWhere($this->mKeyField . "=" . $id);
			return true;
		}
		elseif (!$this->mKeyField) {
			return true;
		}
		else {
			return false;
		}
	}
	
	function insert() {
		if ($this->mKeyField) {
			$this->set($this->mKeyField, "_AUTO_");
			if (0 < ($nextid = Query::insert())) {
				$this->set($this->mKeyField, $nextid);
				$this->cfgWhere($this->mKeyField."='{$nextid}'");
				return $nextid;
			}
			else { return false; }
		}
		else { return Query::insert(); }
	}

	function create($rField) {
		if (!is_array($rField)) { $rField = explode(',', $rField); }
		foreach ($rField as $k => $sField) { $rField[$k] = "{$sField}='".addslashes($this->get($sField))."'"; }
		$this->cfgWhere(implode(' AND ', $rField));
		if ($this->mKeyField) { $this->set($this->mKeyField, 0); }
		$this->load();
		if ($this->mKeyField && 0 < ($id = $this->getID())) {
			$this->set($this->mKeyField, $id);
			$this->cfgWhere($this->mKeyField . "=" . $id);
			return $id;
		}
		elseif ($this->mKeyField) {
			return $this->insert();
		}
		else {
			return $this->replace();
		}
	}

/// attr functions ///
	function getAttr($nID=null) {
		if (!$nID) { $nID = $this->getID(); }
		if (!$nID) { return false; }
		$sql = str_replace(
			array("::FIELD::", "::TABLE::", "::WHERE::", "::GROUP::" ,"::ORDER::"),
			array(
				'id,attr,title',
				$this->mTable.'_attr',
				'WHERE '.$this->mKeyField."='".addslashes($nID)."'",
				'',
				'ORDER BY attr'
			),
			$this->mSqlSelect
		);
		if ($h = mysql_query($sql, $this->mDb)) {
			$rAssoc = array();
			while ($r = mysql_fetch_assoc($h)) {
				$rAssoc[] = $r;
			}
			mysql_free_result($h);
			return $rAssoc;
		}
		else { return false; }				

	}
	function addAttr($nID, $sAttr, $sValue) {
		if (!$nID) { $nID = $this->getID(); }
		if (!$nID) { return false; }
		$sql = str_replace(
			array("::TABLE::", "::DATA::"),
			array(
				$this->mTable.'_attr',
				$this->mKeyField."='".addslashes($nID)."',attr='".addslashes($sAttr)."',title='".addslashes($sValue)."'"
			),
			$this->mSqlInsert
		);
		if (mysql_query($sql, $this->mDb)) { return mysql_insert_id($this->mDb); }
		else { return false; }
	}
	function updateAttr($nID, $sAttr, $sValue) {
		$nID = max(0, (int)$nID);
		if (!$nID) { return false; }
		$sql = str_replace(
			array("::TABLE::", "::DATA::", "::WHERE::"),
			array(
				$this->mTable.'_attr',
				"attr='".addslashes($sAttr)."',title='".addslashes($sValue)."'",
				"WHERE id='{$nID}'"
			),
			$this->mSqlUpdate
		);
		if (mysql_query($sql, $this->mDb)) { return $nID; }
		else { return false; }
	}
	function deleteAttr($nID) {
		$nID = max(0, (int)$nID);
		if (!$nID) { return false; }
		$sql = str_replace(
			array("::TABLE::", "::WHERE::"),
			array(
				$this->mTable.'_attr',
				"WHERE id='{$nID}'"
			),
			$this->mSqlDelete
		);
		if (mysql_query($sql, $this->mDb)) { return true; }
		else { return false; }
	}
	function getAttrLable() {
		return $this->mAttrLable;
	}

/// get functions ///
	function getCfgField($fieldtype) {
		$value = null;
		eval('$value = $this->m' . $fieldtype . 'Field;');
		return $value;
	}

	function getID() {
		return $this->get($this->mKeyField);
	}

	function fetchMore($rMore) { // virtual
		return true;
	}

} /// end class Item.

class ItemList extends Item {
/// definition and constructor ///
	var $mClass = "Item";
	var $mSeq = -1;
	var $mItems = array();
	var $mRankBase = 1;
	
	function ItemList($dsn=null) {
		Item::Item($dsn);
	}

/// configure functions ///
	function cfgClass($classname) {
		$this->mClass = $classname;
	}

/// execute functions ///
	function loadList($limit1=0, $limit2=0) {
		$this->_fetchSql("Select");
		if (0 <= $limit1 && 0 < $limit2) {
			$this->mRankBase = $limit1 + 1;
			$this->mRes = mysql_query($this->mSql . " LIMIT $limit1, $limit2", $this->mDb);
		}
		elseif (0 < $limit1) {
			$this->mRankBase = 1;
			$this->mRes = mysql_query($this->mSql . " LIMIT $limit1", $this->mDb);
		}
		else{
			$this->mRankBase = 1;
			$this->mRes = mysql_query($this->mSql, $this->mDb);
		}
	}

	function load($limit1=0, $limit2=0) {
		$this->loadList($limit1, $limit2);
	}

/// list control functions ///
	function resetList() {
		@mysql_data_seek($this->mRes, 0);
		$this->mSeq = -1;
	}

	function nextItem($save=true) {
		if ($this->nextRecord()) {
			eval('$obj = new ' . $this->mClass . '();');
			$obj->set(null, $this->getData());
			if ($obj->mKeyField) {
				$obj->cfgWhere($obj->mKeyField."=".$obj->getID());
			}
			if ($save) {
				$this->mSeq++;
				if (!isset($this->mItems[$this->mSeq])) {
					$this->mItems[$this->mSeq] = $obj; //! if in php5, here should be = clone $obj;
				}
				return $this->mItems[$this->mSeq];
			}
			else {
				return $obj;
			}
		}
		else {
			return false;
		}
	}

	function saveList() {
		$this->resetList();
		$i = 0;
		while ($this->nextItem()) {
			$i++;
		}
		$this->resetList();
		return $i;
	}

	//! do after load();
	//! need fetchMore(),set() on each oItem;
	function fetchMoreEach($rMore) {
		$this->resetList();
		while ($o = $this->nextItem()) {
			$o->set('Rank', $this->mRankBase + $this->mSeq);
			$o->fetchMore($rMore);
		}
		$this->resetList();
	}

/// get and count functions ///
	function countAll() {
		$tmp_sql = str_replace(
			array("::FIELD::", "::TABLE::", "::WHERE::", "::GROUP::" ,"::ORDER::"),
			array(
				"COUNT(*) cnt",
				($this->mTable ? $this->mTable : ""),
				($this->mWhere ? "WHERE (" . implode(") AND (", $this->mWhere) . ")" : ""),
				"",
				""
			),
			$this->mSqlSelect
		);
//@ echo $tmp_sql."<br />\n";
		$result = mysql_query($tmp_sql, $this->mDb);
		$rec = mysql_fetch_array($result, MYSQL_ASSOC);
		return $rec["cnt"];
	}

	function countResult() {
		return mysql_num_rows($this->mRes);
	}

	function getList() {
		return $this->mItems;
	}

	function fetchArray() {
		$this->resetList();
		$tmp_arr = array();
		while ($tmp_obj = $this->nextItem()) {
			$tmp_arr[] = $tmp_obj->getData();
		}
		$this->resetList();
		return $tmp_arr;
	}

/// set functions ///
	function setList($items) {
		$this->mItems = $items;
	}

} /// end class ItemList.

?>
